// ----------------------------------------------------------
// - Fully Customisable Derma-based Interface -
// ----------------------------------------------------------

// - by [GU]|ZLC|thomasfn -

// VERSION: 1.0.0

// DInterface is the primary table; it is used for everything.
DInterface = {}

// DPlugins is the table used to store plugins.
DPlugins = {}

Msg( "- Uses DMenu Derma Interface (by [GU]|ZLC|thomasfn) -\n" )

// ----------------------------------------------------------

	function DInterface:Setup( X, Y, Width, Height, Title, CloseButton, Draggable )
		if (self["setup"]) then return end
		self["d_main"] = vgui.Create( "DFrame" )
		self["d_main"]:SetPos( X, Y )
		self["d_main"]:SetSize( Width, Height )
		self["d_main"]:SetTitle( Title )
		self["d_main"]:ShowCloseButton( CloseButton )
		self["d_main"]:SetDraggable( Draggable )
		self["d_main"]:SetDeleteOnClose( false )
		self["d_prop"] = vgui.Create( "DPropertySheet" )
		self["d_prop"]:SetParent( self["d_main"] )
		self["d_prop"]:SetPos( 5, 30 )
		self["d_prop"]:SetSize( Width-10, Height-35 )
		self["d_width"] = Width
		self["d_height"] = Height
		self["setup"] = true
		self["finished"] = false
	end
	
	function DInterface:FinishSetup( )
		if (!self["setup"]) then return end
		DPlugins:Run()
		// License Note: You will only be allowed to remove the about menu and it's contents if the author has given you explicit permission.
		// You may however add more information about the gamemode below if you wish, using the AddGamemodeInfo function.
		self:AddCategory( "CAT_ABOUT", "About", "gui/silkicons/group", "About DMenu" )
		self:AddLabel( "lblAbout1", "CAT_ABOUT", "DMenu was written by [GU]|ZLC|thomasfn.", 5, 5 )
		self:AddLabel( "lblAbout2", "CAT_ABOUT", "It is designed for Garry's Mod 10 Lua developers.", 5, 25 )
		self:AddLabel( "lblAbout3", "CAT_ABOUT", "- Version: [1.0.0] (18th July 2008) -", 5, 45 )
		self["about_nexty"] = 85
		self["about_yinc"] = 20
		self["finished"] = true
		self:Hide()
	end
	
	function DInterface:AddGamemodeInfo( ID, Text )
		if (!self["setup"]) then return end
		if (!self["finished"]) then return end
		y = self["about_nexty"]
		self["about_nexty"] = self["about_nexty"] + self["about_yinc"]
		self:AddLabel( "lblAbout" .. tostring(ID+3), "CAT_ABOUT", Text, 5, y )
	end
	
	function DInterface:AddCategory( CName, CTitle, CIcon, CToolTip )
		if (!self["setup"]) then return end
		self["d_prop_l" .. CName] = vgui.Create( "DPanel" )
		self["d_prop_l" .. CName]:SetPos( 0, 0 )
		self["d_prop_l" .. CName]:SetWidth( self:GetWidth()-10, self:GetHeight()-40 )
		self["d_prop_l" .. CName].Paint = function()
			surface.SetDrawColor( 50, 50, 50, 255 )
			surface.DrawRect( 0, 0, self["d_prop_l" .. CName]:GetWide(), self["d_prop_l" .. CName]:GetTall() )
		end
		self["d_prop"]:AddSheet( CTitle, self["d_prop_l" .. CName], CIcon, false, false, CToolTip )
		Tab = self["d_prop"].Items[ #self["d_prop"].Items ].Tab
		self["d_prop_c" .. CName] = Tab
	end
	
	function DInterface:FocusCategory( CName )
		self["d_prop"]:SetActiveTab( self["d_prop_c" .. CName] ) 
	end
	
	function DInterface:Show( )
		if (!self["setup"]) then return end
		if (!self["finished"]) then return end
		self["d_main"]:SetVisible( true )
		self["d_main"]:MakePopup()
	end
	
	function DInterface:Hide( )
		if (!self["setup"]) then return end
		if (!self["finished"]) then return end
		self["d_main"]:SetVisible( false )
		self["d_main"]:Close()
	end
	
	function DInterface:GetWidth( )
		if (!self["setup"]) then return 0 end
		return self["d_width"]
	end
	
	function DInterface:GetHeight( )
		if (!self["setup"]) then return 0 end
		return self["d_height"]
	end
	
	function DInterface:GetAreaX( )
		if (!self["setup"]) then return 0 end
		return self["d_width"]-10
	end
	
	function DInterface:GetAreaY( )
		if (!self["setup"]) then return 0 end
		return self["d_height"]-40
	end
	
	function DInterface:DestroyMe( )
		self = {}
	end
	
// ----------------------------------------------------------

	function DInterface:MakeWindow( WindowName, WindowTitle, X, Y, Width, Height, Draggable, CloseButton )
		self["d_window_w" .. WindowName] = vgui.Create( "DFrame" )
		self["d_window_w" .. WindowName]:SetPos( X, Y )
		self["d_window_w" .. WindowName]:SetSize( Width, Height )
		self["d_window_w" .. WindowName]:SetTitle( WindowTitle )
		self["d_window_w" .. WindowName]:ShowCloseButton( CloseButton )
		self["d_window_w" .. WindowName]:SetDraggable( Draggable )
		self["d_window_w" .. WindowName]:SetDeleteOnClose( false )
		CatName = WTC( WindowName )
		self["d_prop_l" .. CatName] = vgui.Create( "DPanel", self["d_window_w" .. WindowName] )
		self["d_prop_l" .. CatName]:SetPos( 5, 30 )
		self["d_prop_l" .. CatName]:SetSize( Width-10, Height-35 )
		self["d_prop_l" .. CatName].Paint = function()
			surface.SetDrawColor( 50, 50, 50, 255 )
			surface.DrawRect( 0, 0, self["d_prop_l" .. CatName]:GetWide(), self["d_prop_l" .. CatName]:GetTall() )
		end
		DInterface:HideWindow( WindowName )
	end
	
	function DInterface:KillWindow( WindowName )
		self["d_window_w" .. WindowName]:Remove()
		self["d_window_w" .. WindowName] = nil
		CatName = WTC( WindowName )
		self["d_prop_l" .. CatName]:Remove()
		self["d_prop_l" .. CatName] = nil
	end
	
	function DInterface:HideWindow( WindowName )
		self["d_window_w" .. WindowName]:SetVisible( false )
		self["d_window_w" .. WindowName]:Close()
	end
	
	function DInterface:ShowWindow( WindowName )
		self["d_window_w" .. WindowName]:SetVisible( true )
		self["d_window_w" .. WindowName]:MakePopup()
	end
	
	function WTC( WindowName )
		return "_WINDOW_" .. WindowName
	end
	
// ----------------------------------------------------------

	function DInterface:HUDAddPanel( PName, X, Y, Width, Height, Colour )
		self["d_hud_p" .. PName] = vgui.Create( "DPanel" )
		self["d_hud_p" .. PName]:SetPos( X, Y )
		self["d_hud_p" .. PName]:SetSize( Width, Height )
		self["d_hud_p" .. PName].Colour = Colour
		self["d_hud_p" .. PName].Paint = function( self, val )
			draw.RoundedBox( 5, 0, 0, self:GetWide(), self:GetTall(), self.Colour )
		end
		self:HUDShowPanel( PName )
	end
	
	function DInterface:HUDSetPanelColour( PName, Colour )
		self["d_hud_p" .. PName].Colour = Colour
	end
	
	function DInterface:HUDHidePanel( PName )
		self["d_hud_p" .. PName]:SetVisible( false )
	end
	
	function DInterface:HUDShowPanel( PName )
		self["d_hud_p" .. PName]:SetVisible( true )
	end
	
	function DInterface:HUDAddBar( BName, X, Y, Width, Height, BackColour, ForeColour )
		self["d_hud_b" .. BName] = vgui.Create( "DPanel" )
		self["d_hud_b" .. BName]:SetPos( X, Y )
		self["d_hud_b" .. BName]:SetSize( Width, Height )
		self["d_hud_b" .. BName].BackColour = BackColour
		self["d_hud_b" .. BName].ForeColour = ForeColour
		self["d_hud_b" .. BName].Value = 0
		self["d_hud_b" .. BName].Paint = function( self, val )
			draw.RoundedBox( 5, 0, 0, self:GetWide(), self:GetTall(), self.BackColour )
			if (self.Value > 0) then draw.RoundedBox( 5, 2, 2, (self:GetWide()-4) * self.Value, self:GetTall()-4, self.ForeColour ) end
		end
		self:HUDShowBar( BName )
	end
	
	function DInterface:HUDSetBar( BName, Value )
		self["d_hud_b" .. BName].Value = Value
	end
	
	function DInterface:HUDHideBar( BName )
		self["d_hud_b" .. BName]:SetVisible( false )
	end
	
	function DInterface:HUDShowBar( BName )
		self["d_hud_b" .. BName]:SetVisible( true )
	end	
	
// ----------------------------------------------------------

	function DInterface:MakePanel( PName, CName, X, Y, Width, Height, paint )
		PanelName = PTC( PName )
		self["d_prop_l" .. PanelName] = vgui.Create( "DPanel" )
		self["d_prop_l" .. PanelName]:SetPos( X, Y )
		self["d_prop_l" .. PanelName]:SetSize( Width, Height )
		self["d_prop_l" .. PanelName]:SetParent( self["d_prop_l" .. CName] )
		self["d_prop_l" .. PanelName].Paint = paint
		return self["d_prop_l" .. PanelName]
	end
	
	function DInterface:HidePanel( PName )
		PanelName = PTC( PName )
		self["d_prop_l" .. PanelName]:SetVisible( false )
	end
	
	function DInterface:ShowPanel( PName )
		PanelName = PTC( PName )
		self["d_prop_l" .. PanelName]:SetVisible( true )
	end
	
	function DInterface:GetPanel( PName )
		PanelName = PTC( PName )
		return self["d_prop_l" .. PanelName]
	end
	
	function PTC( PName )
		return "_PANEL_" .. PName
	end

// ----------------------------------------------------------

	function DInterface:AddLabel( LName, CName, Text, X, Y )
		if (!self["setup"]) then return end
		self["d_prop_l" .. CName .. "_l" .. LName] = vgui.Create( "DLabel" )
		self["d_prop_l" .. CName .. "_l" .. LName]:SetPos( X, Y )
		self["d_prop_l" .. CName .. "_l" .. LName]:SetText( Text )
		self["d_prop_l" .. CName .. "_l" .. LName]:SetParent( self["d_prop_l" .. CName] )
		self["d_prop_l" .. CName .. "_l" .. LName]:SizeToContents()
	end
	
	function DInterface:SetLabelText( LName, CName, Text )
		if (!self["setup"]) then return end
		self["d_prop_l" .. CName .. "_l" .. LName]:SetText( Text )
		self["d_prop_l" .. CName .. "_l" .. LName]:SizeToContents()
	end
	
	function DInterface:AddSpawnIcon( SIName, CName, ModelName, X, Y )
		if (!self["setup"]) then return end
		self["d_prop_l" .. CName .. "_si" .. SIName] = vgui.Create( "SpawnIcon" )
		self["d_prop_l" .. CName .. "_si" .. SIName]:SetPos( X, Y )
		self["d_prop_l" .. CName .. "_si" .. SIName]:SetModel( ModelName )
		self["d_prop_l" .. CName .. "_si" .. SIName]:SetParent( self["d_prop_l" .. CName] )
	end
	
	function DInterface:AddHTML( HName, CName, HTML, X, Y, Width, Height )
		if (!self["setup"]) then return end
		self["d_prop_l" .. CName .. "_html" .. HName] = vgui.Create( "HTML" )
		self["d_prop_l" .. CName .. "_html" .. HName]:SetPos( X, Y )
		self["d_prop_l" .. CName .. "_html" .. HName]:SetHTML( HTML )
		self["d_prop_l" .. CName .. "_html" .. HName]:SetParent( self["d_prop_l" .. CName] )
		self["d_prop_l" .. CName .. "_html" .. HName]:SetSize( Width, Height )
	end
	
	function DInterface:SetHTMLText( HName, CName, HTML )
		if (!self["setup"]) then return end
		if (!self["d_prop_l" .. CName .. "_html" .. HName]) then return end
		self["d_prop_l" .. CName .. "_html" .. HName]:SetHTML( HTML )
	end
	
	function DInterface:AddButton( BName, CName, Text, X, Y, Width, Height, CallBack )
		if (!self["setup"]) then return end
		self["d_prop_l" .. CName .. "_b" .. BName] = vgui.Create( "DButton" )
		self["d_prop_l" .. CName .. "_b" .. BName]:SetPos( X, Y )
		self["d_prop_l" .. CName .. "_b" .. BName]:SetSize( Width, Height )
		self["d_prop_l" .. CName .. "_b" .. BName]:SetText( Text )
		self["d_prop_l" .. CName .. "_b" .. BName]:SetParent( self["d_prop_l" .. CName] )
		if (!CallBack) then CallBack = function() end; end
		self["d_prop_l" .. CName .. "_b" .. BName].DoClick = CallBack
		self["d_prop_l" .. CName .. "_b" .. BName].DoRightClick = CallBack
		return self["d_prop_l" .. CName .. "_b" .. BName]
	end
	
	function DInterface:AddTextbox( TBName, CName, DefaultValue, X, Y, Width, Height, CallBack )
		if (!self["setup"]) then return end
		self["d_prop_l" .. CName .. "_tb" .. TBName] = vgui.Create( "DTextEntry" )
		self["d_prop_l" .. CName .. "_tb" .. TBName]:SetPos( X, Y )
		self["d_prop_l" .. CName .. "_tb" .. TBName]:SetSize( Width, Height )
		self["d_prop_l" .. CName .. "_tb" .. TBName]:SetText( DefaultValue )
		self["d_prop_l" .. CName .. "_tb" .. TBName]:SetParent( self["d_prop_l" .. CName] )
		if (!CallBack) then CallBack = function() end; end
		self["d_prop_l" .. CName .. "_tb" .. TBName].OnEnter = CallBack
		self["d_prop_l" .. CName .. "_tb" .. TBName]:SetEnterAllowed( true )
		return self["d_prop_l" .. CName .. "_tb" .. TBName]
	end
	
	function DInterface:SetTextboxText( TBName, CName, Text )
		if (!self["setup"]) then return end
		if (!self["d_prop_l" .. CName .. "_tb" .. TBName]) then return end
		self["d_prop_l" .. CName .. "_tb" .. TBName]:SetText( Text )
	end
	
	function DInterface:AddImage( IName, CName, X, Y, Filename, OnClick )
		if (!self["setup"]) then return end
		self["d_prop_l" .. CName .. "_i" .. IName] = vgui.Create( "DImageButton" )
		self["d_prop_l" .. CName .. "_i" .. IName]:SetPos( X, Y )
		self["d_prop_l" .. CName .. "_i" .. IName]:SetImage( Filename )
		self["d_prop_l" .. CName .. "_i" .. IName]:SetParent( self["d_prop_l" .. CName] )
		self["d_prop_l" .. CName .. "_i" .. IName].DoClick = OnClick
		self["d_prop_l" .. CName .. "_i" .. IName]:SizeToContents()
	end
	
	function DInterface:AddCheckbox( CBName, CName, Text, X, Y, DefaultValue, OnChange )
		if (!self["setup"]) then return end
		self["d_prop_l" .. CName .. "_cb" .. CBName] = vgui.Create( "DCheckBoxLabel" )
		self["d_prop_l" .. CName .. "_cb" .. CBName]:SetPos( X, Y )
		self["d_prop_l" .. CName .. "_cb" .. CBName]:SetParent( self["d_prop_l" .. CName] )
		self["d_prop_l" .. CName .. "_cb" .. CBName]:SetText( Text )
		self["d_prop_l" .. CName .. "_cb" .. CBName]:SizeToContents()
		self["d_prop_l" .. CName .. "_cb" .. CBName]:SetValue( DefaultValue )
		if (!OnChange) then OnChange = function() end; end
		self["d_prop_l" .. CName .. "_cb" .. CBName].OnChange = OnChange
	end
	
	function DInterface:AddSlider( SName, CName, Text, X, Y, Width, Height, Min, Max, Decimal )
		if (!self["setup"]) then return end
		self["d_prop_l" .. CName .. "_s" .. SName] = vgui.Create( "DNumSlider" )
		self["d_prop_l" .. CName .. "_s" .. SName]:SetPos( X, Y )
		self["d_prop_l" .. CName .. "_s" .. SName]:SetParent( self["d_prop_l" .. CName] )
		self["d_prop_l" .. CName .. "_s" .. SName]:SetText( Text )
		self["d_prop_l" .. CName .. "_s" .. SName]:SetSize( Width, Height )	
		self["d_prop_l" .. CName .. "_s" .. SName]:SetMin( Min )
		self["d_prop_l" .. CName .. "_s" .. SName]:SetMax( Max )
		self["d_prop_l" .. CName .. "_s" .. SName]:SetDecimals( Decimal )
	end
	
	function DInterface:AddTable( TBLName, CName, X, Y, Width, Height )
		if (!self["setup"]) then return end
		self["d_prop_l" .. CName .. "_tbl" .. TBLName] = vgui.Create( "DListView" )
		self["d_prop_l" .. CName .. "_tbl" .. TBLName]:SetPos( X, Y )
		self["d_prop_l" .. CName .. "_tbl" .. TBLName]:SetParent( self["d_prop_l" .. CName] )
		self["d_prop_l" .. CName .. "_tbl" .. TBLName]:SetSize( Width, Height )
		self["d_prop_l" .. CName .. "_tbl" .. TBLName]:SetMultiSelect( false )
	end
	
	function DInterface:TableAddRow( TBLName, CName, ValueA, ValueB, ValueC, ValueD, ValueE, ValueF, ValueG, ValueH )
		if (!self["setup"]) then return end
		return self["d_prop_l" .. CName .. "_tbl" .. TBLName]:AddLine( ValueA, ValueB, ValueC, ValueD, ValueE, ValueF, ValueG, ValueH )
	end
	
	function DInterface:TableAddColumn( TBLName, CName, ColName )
		if (!self["setup"]) then return end
		self["d_prop_l" .. CName .. "_tbl" .. TBLName]:AddColumn( ColName )
	end
	
	function DInterface:TableClearRows( TBLName, CName )
		if (!self["setup"]) then return end
		self["d_prop_l" .. CName .. "_tbl" .. TBLName]:Clear()
	end	
	
	function DInterface:AddListbox( LBName, CName, X, Y, Width, Height, OnSelect )
		if (!self["setup"]) then return end
		self["d_prop_l" .. CName .. "_lb" .. LBName] = vgui.Create( "DComboBox" )
		self["d_prop_l" .. CName .. "_lb" .. LBName]:SetParent( self["d_prop_l" .. CName] )
		self["d_prop_l" .. CName .. "_lb" .. LBName]:SetPos( X, Y )
		self["d_prop_l" .. CName .. "_lb" .. LBName]:SetSize( Width, Height )
		self["d_prop_l" .. CName .. "_lb" .. LBName]:SetMultiple( false )
	end
	
	function DInterface:ListboxAddItem( LBName, CName, Text )
		if (!self["setup"]) then return end
		self["d_prop_l" .. CName .. "_lb" .. LBName]:AddItem( Text )
	end
	
// ----------------------------------------------------------
	
	function DInterface:GetTextboxValue( TBName, CName )
		if (!self["setup"]) then return "" end
		return self["d_prop_l" .. CName .. "_tb" .. TBName]:GetValue()
	end

	function DInterface:GetCheckboxValue( CBName, CName )
		if (!self["setup"]) then return 0 end
		return self["d_prop_l" .. CName .. "_cb" .. CBName]:GetChecked()
	end
	
	function DInterface:GetSliderValue( SName, CName )
		if (!self["setup"]) then return 0 end
		return self["d_prop_l" .. CName .. "_s" .. SName]:GetValue()
	end
	
	function DInterface:GetListboxValue( LBName, CName )
		if (!self["setup"]) then return "" end
		return self["d_prop_l" .. CName .. "_lb" .. LBName]:GetSelectedItems()[1]:GetValue()
	end
	
	function DInterface:GetTableSelectedValue( TBLName, CName, ColID )
		if (!self["setup"]) then return "" end
		return self["d_prop_l" .. CName .. "_tbl" .. TBLName]:GetSelected()[1]:GetColumnText(ColID)
	end
	
	function DInterface:GetTableSelectedLine( TBLName, CName, ColID )
		if (!self["setup"]) then return "" end
		return self["d_prop_l" .. CName .. "_tbl" .. TBLName]:GetSelectedLine()
	end
	
// ----------------------------------------------------------
	
	function DInterface:RemoveLabel( LName, CName )
		if (!self["setup"]) then return end
		if (!self["d_prop_l" .. CName .. "_l" .. LName]) then return end
		self["d_prop_l" .. CName .. "_l" .. LName]:Remove()
		self["d_prop_l" .. CName .. "_l" .. LName] = nil
	end
	
	function DInterface:RemoveSpawnIcon( SIName, CName )
		if (!self["setup"]) then return end
		self["d_prop_l" .. CName .. "_si" .. SIName]:Remove()
		self["d_prop_l" .. CName .. "_si" .. SIName] = nil
	end
	
	function DInterface:RemoveHTML( HName, CName )
		if (!self["setup"]) then return end
		if (!self["d_prop_l" .. CName .. "_html" .. HName]) then return end
		self["d_prop_l" .. CName .. "_html" .. HName]:Remove()
		self["d_prop_l" .. CName .. "_html" .. HName] = nil
	end
	
	function DInterface:RemoveButton( BName, CName )
		if (!self["setup"]) then return end
		if (!self["d_prop_l" .. CName .. "_b" .. BName]) then return end
		self["d_prop_l" .. CName .. "_b" .. BName]:Remove()
		self["d_prop_l" .. CName .. "_b" .. BName] = nil
	end
	
	function DInterface:RemoveTextbox( TBName, CName )
		if (!self["setup"]) then return end
		if (!self["d_prop_l" .. CName .. "_tb" .. TBName]) then return end
		self["d_prop_l" .. CName .. "_tb" .. TBName]:Remove()
		self["d_prop_l" .. CName .. "_tb" .. TBName] = nil
	end
	
	function DInterface:RemoveImage( IName, CName )
		if (!self["setup"]) then return end
		self["d_prop_l" .. CName .. "_i" .. IName]:Remove()
		self["d_prop_l" .. CName .. "_i" .. IName] = nil
	end
	
	function DInterface:RemoveCheckbox( CBName, CName )
		if (!self["setup"]) then return end
		self["d_prop_l" .. CName .. "_cb" .. CBName]:Remove()
		self["d_prop_l" .. CName .. "_cb" .. CBName] = nil
	end
	
	function DInterface:RemoveSlider( SName, CName )
		if (!self["setup"]) then return end
		self["d_prop_l" .. CName .. "_l" .. SName]:Remove()
		self["d_prop_l" .. CName .. "_l" .. SName] = nil
	end
	
	function DInterface:RemoveTable( TBLName, CName )
		if (!self["setup"]) then return end
		if (!self["d_prop_l" .. CName .. "_tbl" .. TBLName]) then return end
		self["d_prop_l" .. CName .. "_tbl" .. TBLName]:Remove()
		self["d_prop_l" .. CName .. "_tbl" .. TBLName] = nil
	end
	
// ----------------------------------------------------------

	function DInterface:GetObject( OName, Prefix, CName )
		if (!self["setup"]) then return end
		return self["d_prop_l" .. CName .. "_" .. Prefix .. OName]
	end
	
	function DInterface:SetObjectPosition( OName, Prefix, CName, X, Y )
		if (!self["setup"]) then return end
		self["d_prop_l" .. CName .. "_" .. Prefix .. OName]:SetPos( X, Y )
	end
	
	function DInterface:SetObjectSize( OName, Prefix, CName, Width, Height )
		if (!self["setup"]) then return end
		self["d_prop_l" .. CName .. "_" .. Prefix .. OName]:SetSize( Width, Height )
	end
	
	function DInterface:RenameObject( OName, Prefix, CName, NewName )
		if (!self["setup"]) then return end
		// Rename object without losing the control and without losing the reference
		local OldObject = self["d_prop_l" .. CName .. "_" .. Prefix .. OName]
		self["d_prop_l" .. CName .. "_" .. Prefix .. NewName] = OldObject
		self["d_prop_l" .. CName .. "_" .. Prefix .. OName] = nil
	end
	
// ----------------------------------------------------------

	function DPlugins:Run()
		for id=1,#self do
			self[id]()
		end
	end
	
	function DPlugins:AddPlugin( CallBack )
		id = #self + 1
		self[id] = CallBack
	end
	
// ----------------------------------------------------------